package com.example.work.check;

import com.example.work.Excel.*;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 资产导入服务类
 * 负责根据文件名格式识别文件类型并导入到相应的列表中
 */
@Component
@Data
public class AssetImportService {

    @Autowired
    AssetComparisonService assetComparisonService;

    // 文件名正则表达式: {id}-{type}.xlsx
    private static final Pattern FILE_NAME_PATTERN = Pattern.compile("^(\\d+)-(.*)\\.xlsx?$");

    // 存储不同类型的资产列表
    private List<DatabaseAssetXlsx> databaseAssetList = new ArrayList<>();
    private List<ServerAssetXlsx> serverAssetList = new ArrayList<>();
    private List<WebAssetXlsx> webAssetList = new ArrayList<>();
    private List<MiddlewareXlsx> middlewareAssetList = new ArrayList<>();
    private List<LoadBalancerXlsx> loadBalancerAssetList = new ArrayList<>();
    private List<OtherApplicationSoftwareXlsx> otherApplicationSoftwareAssetList = new ArrayList<>();
    private List<OtherAssetXlsx> otherAssetList = new ArrayList<>();


    private List<Firewall> firewallList = new ArrayList<>();
    private List<SecurityProduct> securityProductList = new ArrayList<>();
    private List<Router> routerList = new ArrayList<>();
    private List<Switch> switchList = new ArrayList<>();
    private List<SupplyChainManagementSystem> supplyChainList = new ArrayList<>();


    private List<AssetReportZhiwang> assetReportZhiwangList =  new ArrayList<>();

    private List<AssetEntity> assetEntities =  new ArrayList<>();


    /**
     * 导入单个文件
     *
     * @param filePath 文件路径
     * @return 导入是否成功
     */
    public boolean importSingleFile(String filePath) {
        try {
            File file = new File(filePath);
            if (!file.exists()) {
                System.err.println("文件不存在: " + filePath);
                return false;
            }

            String fileName = file.getName();
            AssetFileInfo fileInfo = parseFileName(fileName);

            if (fileInfo == null) {
                System.err.println("无法解析文件名: " + fileName);
                return false;
            }

            return importFileByType(filePath, fileInfo);

        } catch (Exception e) {
            System.err.println("导入文件失败: " + filePath + ", 错误: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 批量导入指定目录下的所有Excel文件
     *
     * @param directoryPath 目录路径
     * @return 成功导入的文件数量
     */
    public int importFromDirectory(String directoryPath) {
        File directory = new File(directoryPath);
        if (!directory.exists() || !directory.isDirectory()) {
            System.err.println("目录不存在: " + directoryPath);
            return 0;
        }

        File[] files = directory.listFiles((dir, name) ->
                name.toLowerCase().endsWith(".xlsx") || name.toLowerCase().endsWith(".xls"));

        if (files == null || files.length == 0) {
            System.out.println("目录中没有找到Excel文件: " + directoryPath);
            return 0;
        }

        int successCount = 0;
        for (File file : files) {
            if (importSingleFile(file.getAbsolutePath())) {
                successCount++;
            }
        }

        System.out.println("批量导入完成，成功导入 " + successCount + "/" + files.length + " 个文件");
        return successCount;
    }

    /**
     * 根据文件类型导入数据
     */
    @SuppressWarnings("unchecked")
    private boolean importFileByType(String filePath, AssetFileInfo fileInfo) {
        try {
            AssetTypeEnum assetType = fileInfo.getAssetType();
            Class<?> entityClass = assetType.getEntityClass();

            System.out.println("开始导入文件: " + filePath + " (类型: " + assetType.getTypeName() + ")");

            List<?> importedData = ExcelImportUtil.importFromExcel(filePath, entityClass);

            // 根据类型将数据添加到相应的列表中
            switch (assetType) {
                case DATABASE:
                    databaseAssetList.addAll((List<DatabaseAssetXlsx>) importedData);
                    break;
                case SERVER:
                    serverAssetList.addAll((List<ServerAssetXlsx>) importedData);
                    break;
                case WEB:
                    webAssetList.addAll((List<WebAssetXlsx>) importedData);
                    break;
                case MIDDLEWARE:
                    middlewareAssetList.addAll((List<MiddlewareXlsx>) importedData);
                    break;
                case LOAD_BALANCER:
                    loadBalancerAssetList.addAll((List<LoadBalancerXlsx>) importedData);
                    break;
                case OTHER_APPLICATION_SOFTWARE:
                    otherApplicationSoftwareAssetList.addAll((List<OtherApplicationSoftwareXlsx>) importedData);
                    break;
                case OTHER:
                    otherAssetList.addAll((List<OtherAssetXlsx>) importedData);
                    break;

                case FIREWALL:
                    firewallList.addAll((List<Firewall>) importedData);
                    break;
                case SECURITY_PRODUCT:
                    securityProductList.addAll((List<SecurityProduct>) importedData);
                    break;
                case ROUTER:
                    routerList.addAll((List<Router>) importedData);
                    break;
                case SUPPLY_CHAIN:
                    supplyChainList.addAll((List<SupplyChainManagementSystem>) importedData);
                    break;
                case SWITCH:
                    switchList.addAll((List<Switch>) importedData);
                    break;
                case All:
                    assetReportZhiwangList.addAll((List<AssetReportZhiwang>) importedData);
                    break;
                case Comparison:
                    assetEntities.addAll((List<AssetEntity>) importedData);
                    break;

                default:
                    System.err.println("未知的资产类型: " + assetType);
                    return false;
            }

            System.out.println("成功导入 " + importedData.size() + " 条记录到 " + assetType.getTypeName() + " 列表");
            return true;

        } catch (Exception e) {
            System.err.println("导入文件失败: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 解析文件名，提取ID和类型信息
     *
     * @param fileName 文件名（如: 1103470821239820288-数据库.xlsx）
     * @return 文件信息对象
     */
    private AssetFileInfo parseFileName(String fileName) {
        Matcher matcher = FILE_NAME_PATTERN.matcher(fileName);
        if (!matcher.matches()) {
            return null;
        }

        String id = matcher.group(1);
        String typeName = matcher.group(2);

        try {
            AssetTypeEnum assetType = AssetTypeEnum.fromTypeName(typeName);
            return new AssetFileInfo(id, typeName, assetType);
        } catch (IllegalArgumentException e) {
            System.err.println("未知的资产类型: " + typeName);
            return null;
        }
    }

    /**
     * 获取所有类型的资产数量统计
     */
    public Map<String, Integer> getAssetCountStatistics() {
        Map<String, Integer> statistics = new LinkedHashMap<>();
        statistics.put("数据库", databaseAssetList.size());
        statistics.put("服务器", serverAssetList.size());
        statistics.put("Web", webAssetList.size());
        statistics.put("中间件", middlewareAssetList.size());
        statistics.put("负载均衡", loadBalancerAssetList.size());
        statistics.put("其他应用软件", otherApplicationSoftwareAssetList.size());
        statistics.put("其他", otherAssetList.size());
        return statistics;
    }

    /**
     * 打印统计信息
     */
    public void printStatistics() {
        System.out.println("\n=== 资产导入统计 ===");
        Map<String, Integer> statistics = getAssetCountStatistics();
        int total = 0;

        for (Map.Entry<String, Integer> entry : statistics.entrySet()) {
            int count = entry.getValue();
            System.out.println(entry.getKey() + ": " + count + " 条");
            total += count;
        }

        System.out.println("总计: " + total + " 条记录");
        System.out.println("==================\n");
    }

    /**
     * 与数据库数据进行比对
     *
     * @return 比对结果
     */
    public ComparisonResult compareWithDatabase() {
//        AssetComparisonService comparisonService = new AssetComparisonService();
        return assetComparisonService.compareAssets8(this);
    }

    /**
     * 与数据库数据进行比对（使用自定义的数据库服务）
     *
     * @param mockDatabaseService 自定义的模拟数据库服务
     * @return 比对结果
     */
    public ComparisonResult compareWithDatabase(MockDatabaseService mockDatabaseService) {
        AssetComparisonService comparisonService = new AssetComparisonService(mockDatabaseService);
        return comparisonService.compareAssets(this);
    }

    /**
     * 导入并比对数据的一站式方法
     *
     * @param directoryPath Excel文件目录
     * @return 比对结果，如果导入失败返回null
     */
    public ComparisonResult importAndCompare(String directoryPath) {
        // 先清空现有数据
        clearAllLists();

        // 导入Excel数据
        int importedCount = importFromDirectory(directoryPath);
        if (importedCount == 0) {
            System.out.println("没有成功导入任何Excel文件，无法进行比对");
            return null;
        }

        System.out.println("Excel导入成功，开始与数据库数据进行比对...");

        // 与数据库数据进行比对
        return compareWithDatabase();
    }

    /**
     * 清空所有列表
     */
    public void clearAllLists() {
        databaseAssetList.clear();
        serverAssetList.clear();
        webAssetList.clear();
        middlewareAssetList.clear();
        loadBalancerAssetList.clear();
        otherApplicationSoftwareAssetList.clear();
        otherAssetList.clear();
        System.out.println("已清空所有资产列表");
    }


    /**
     * 文件信息内部类
     */
    private static class AssetFileInfo {
        private final String id;
        private final String typeName;
        private final AssetTypeEnum assetType;

        public AssetFileInfo(String id, String typeName, AssetTypeEnum assetType) {
            this.id = id;
            this.typeName = typeName;
            this.assetType = assetType;
        }

        public String getId() {
            return id;
        }

        public String getTypeName() {
            return typeName;
        }

        public AssetTypeEnum getAssetType() {
            return assetType;
        }

        @Override
        public String toString() {
            return "AssetFileInfo{" +
                    "id='" + id + '\'' +
                    ", typeName='" + typeName + '\'' +
                    ", assetType=" + assetType +
                    '}';
        }


    }
}